#include "timer.hxx"

#include <boost/bind.hpp>
#include <iostream>
#include <time.h>

Timer::Timer() : mCanExit(false)
{
}

Timer::~Timer()
{
	mCanExit = true;
	mThread->join();
}

double
Timer::getTime()
{
      struct timeval tTime;
      gettimeofday(&tTime, 0);

      double llCount = tTime.tv_usec/1000000.0;
      llCount += (double)tTime.tv_sec;
      return (double)llCount;
}

void 
Timer::checkThread() 
{
	if (!mTimerMap.empty()) 
	{
		mCanExit = false;
		mThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&Timer::onThreadRun, this)));
	}
}

Timer::TimerDataPtr 
Timer::addTimer(Timer::TimerCallback *callback, void *userData, unsigned int interval)
{
	Timer::TimerDataPtr ptr = Timer::TimerDataPtr(new Timer::TimerData(userData, interval,shared_from_this()));

	Timer::TimerMapData mapData(callback, 0, ptr);
	mTimerMap[ptr.get()] = mapData;

	checkThread();
	return ptr;
}

void
Timer::onThreadRun()
{
	std::cout << "thread\n";
	while (!mCanExit) 
	{
		usleep(100000);
		double nowTime = getTime();
		for (std::map<void *, TimerMapData>::iterator iter = mTimerMap.begin(); iter != mTimerMap.end(); ++iter)
		{
			TimerMapData &data = iter->second;
			if (nowTime > (data.mLastFireTime + (data.mTimerData->getInterval()/1000.0f))) 
			{
				data.mCallback->onTimer(data.mTimerData);
				data.mLastFireTime = nowTime;
			}
		}
	}
}
